package com.bestv.search.management.command;

import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.*;
import com.bestv.search.common.service.*;
import com.bestv.search.common.util.ChineseCharToEn;
import com.bestv.search.common.util.CommandException;
import com.bestv.search.common.util.DateUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.util.*;

public class EntranceCommand {

    protected final Log log = LogFactory.getLog(getClass());
    private EntranceManager entranceManager;
    private SiteManager siteManager;
    private TargetTypeManager targetTypeManager;
    private SubTypeManager subTypeManager;
    private TypeManager typeManager;

    public TargetTypeManager getTargetTypeManager() {
        return targetTypeManager;
    }

    public void setTargetTypeManager(TargetTypeManager targetTypeManager) {
        this.targetTypeManager = targetTypeManager;
    }

    public SubTypeManager getSubTypeManager() {
        return subTypeManager;
    }

    public void setSubTypeManager(SubTypeManager subTypeManager) {
        this.subTypeManager = subTypeManager;
    }

    public EntranceManager getEntranceManager() {
        return entranceManager;
    }

    public void setEntranceManager(EntranceManager entranceManager) {
        this.entranceManager = entranceManager;
    }

    public String delete(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String[] id = map.get("id");
        entranceManager.deleteEntrance(dsKey, new Long(id[0]));
        return "{'result':'success','message':''}";
    }

    public String get(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";
        String[] id = map.get("id");

        Entrance entrance = entranceManager.getEntranceById(dsKey, new Long(id[0]));
        if (entrance != null) {
            try {
                JSONObject jo = new JSONObject();
                jo.put("id", String.valueOf(entrance.getId()));
                jo.put("name", entrance.getName());
                jo.put("tags", entrance.getTags());
                if (entrance.getTargetType() != null)
                    jo.put("targetType", entrance.getTargetType().getId());
                jo.put("url", entrance.getUrl());
                if (entrance.getSubType() != null)
                    jo.put("subType", entrance.getSubType().getId());
                String startDate = DateUtil.convertDateToString("yyyy-MM-dd", entrance.getStartTime());
                String startTime = DateUtil.convertDateToString("HH:mm", entrance.getStartTime());
                String endDate = DateUtil.convertDateToString("yyyy-MM-dd", entrance.getEndTime());
                String endTime = DateUtil.convertDateToString("HH:mm", entrance.getEndTime());
                jo.put("startDate", startDate);
                jo.put("startTime", startTime);
                jo.put("endDate", endDate);
                jo.put("endTime", endTime);
                jo.put("description", entrance.getDescription());

                List<JSONObject> sites = new ArrayList<JSONObject>();
                Iterator<Site> it = entrance.getSites().iterator();
                while (it.hasNext()) {
                    Site site = it.next();
                    JSONObject siteJson = new JSONObject();
                    siteJson.put("id", site.getId());
                    sites.add(siteJson);
                }
                JSONArray siteArray = new JSONArray(sites.toArray());
                jo.put("sites", siteArray);
                result = jo.toString();
            } catch (JSONException e) {
                log.error(e);
                throw new CommandException();
            }
        }
        return result;
    }

    public String getEntranceSiteIds(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String result = "";
        String[] id = map.get("id");

        Entrance entrance = entranceManager.getEntranceById(dsKey, new Long(id[0]));
        if (entrance != null) {
            String siteIds = "";
            Iterator<Site> it = entrance.getSites().iterator();
            while (it.hasNext()) {
                Site site = it.next();
                siteIds += site.getId() + " ";
            }
            result = "{'siteIds':'" + siteIds + "'}";
        }
        return result;
    }

    public String find(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";

        List<Entrance> entrances = entranceManager.getEntrances(dsKey);
        List<JSONObject> list = new ArrayList<JSONObject>();
        try {
            for (Entrance entrance : entrances) {
                list.add(entranceToJson(entrance));
            }
            JSONArray jsonArray = new JSONArray(list.toArray());
            result = "{'entrances' : " + jsonArray.toString() + "}";
        } catch (JSONException e) {
            log.error(e);
            throw new CommandException();
        }
        return result;
    }

    public String findComm(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";
        String[] typename = map.get("typename");

        List<Entrance> entrances = entranceManager.getComms(dsKey, typename[0]);
        List<JSONObject> list = new ArrayList<JSONObject>();
        try {
            for (Entrance entrance : entrances) {
                list.add(entranceToJson(entrance));
            }
            JSONArray jsonArray = new JSONArray(list.toArray());
            result = "{'entrances' : " + jsonArray.toString() + "}";
        } catch (JSONException e) {
            log.error(e);
            throw new CommandException();
        }
        return result;
    }

    public String save(SysUser user, Map<String, String[]> map, DataSourceKey key) throws ParseException {
        String result = "";
        String[] id = map.get("id");
        String[] name = map.get("name");
        String[] url = map.get("url");
        String[] vdate = map.get("vdate");
        String[] vtime = map.get("vtime");
        String[] invdate = map.get("invdate");
        String[] invtime = map.get("invtime");
        String[] tags = map.get("tags");
        String[] target = map.get("target");
        String[] subType = map.get("subtype");
        String[] description = map.get("description");
        String[] siteCodes = map.get("siteCode");

        /**
         * 在各个驻地做，相同url的入口存在性判断
         */
        // if HDQ operation
        if ("HDQ".equals(user.getSite().getCode())) {
            for (int i = 0; i < siteCodes.length; ++i) {

                key = DataSourceKeyUtil.convert(siteCodes[i]);
                Entrance entranceExist = entranceManager.getEntranceByUrl(key, url[0]);
                if (entranceExist != null) {
                    // 如果驻地已经创建过相同url的入口，那么中央就无法新建或者修改
                    if (!"HDQ".equals(entranceExist.getOwner().getCode())) {
                        Site site = siteManager.getSiteByCode(key, siteCodes[i]);
                        return "{'result':'failure','message':'" + site.getName() + "驻地已经创建过相同URL的入口！" + "'}";
                    }
                    // 否则，表示驻地没有创建过，存在的入口本来就是中央创建的。那么判断当前操作是否是修改还是新建
                    if (!"".equals(id[0])) {
                        if (entranceExist.getId() != new Long(id[0])) {
                            Site site = siteManager.getSiteByCode(key, siteCodes[i]);
                            return "{'result':'failure','message':'" + site.getName() + "驻地已经存在相同URL的入口！" + "'}";
                        }
                    } else {
                        Site site = siteManager.getSiteByCode(key, siteCodes[i]);
                        return "{'result':'failure','message':'" + site.getName() + "驻地已经存在相同URL的入口！" + "'}";
                    }
                }
            }
        } else {
            key = DataSourceKeyUtil.convert(user.getSite().getCode());
            Entrance entranceExist = entranceManager.getEntranceByUrl(key, url[0]);
            /**
             * 相同url的入口存在性判断
             */
            if (entranceExist != null) {
                // 如果是修改
                if (!"".equals(id[0])) {
                    if (entranceExist.getId() != new Long(id[0]))
                        return "{'result':'failure','message':'url'}";
                } else
                    return "{'result':'failure','message':'url'}";
            }
        }
        /**
         * 开始 save 操作
         */
        Entrance entrance = null;
        // if new
        if ("".equals(id[0])) {
            entrance = new Entrance();
            entrance.setCreator(user);
            entrance.setCreateTime(new Date());
            entrance.setUpdateFlag(1);
            entrance.setOwner(user.getSite());

        } else {
            key = DataSourceKeyUtil.convert(user.getSite().getCode());
            entrance = entranceManager.getEntranceById(key, new Long(id[0]));
            if (entrance == null)
                entrance = new Entrance();
            entrance.setUpdateFlag(2); // updateFlag=2表示修改
            entrance.getSites().clear();
            entrance.getTags().clear();
        }
        entrance.setName(name[0]);
        entrance.setNamePY(ChineseCharToEn.getAllFirstLetter(name[0]));
        log.debug("name: " + entrance.getName());
        log.debug("name pinyin: " + entrance.getNamePY());
        entrance.setUrl(url[0]);
        if (!"".equals(tags[0])) {
            String[] tagList = tags[0].split(" ");
            for (String s : tagList) {
                Tag tag = new Tag();
                // tag.setInfo(entrance);
                tag.setTag(s);
                entrance.getTags().add(tag);
            }
        }
        entrance.setDescription(description[0]);
        String sDate = "";
        String eDate = "";
        if (!"".equals(vtime[0]))
            sDate = vdate[0] + vtime[0];
        else
            sDate = vdate[0] + "9:00";
        Date startTime = DateUtil.convertStringToDate("yyyy-MM-ddHH:mm", sDate);
        entrance.setStartTime(startTime);

        if (!"".equals(invtime[0]))
            eDate = invdate[0] + invtime[0];
        else
            eDate = invdate[0] + "23:59";
        Date endTime = DateUtil.convertStringToDate("yyyy-MM-ddHH:mm", eDate);
        entrance.setEndTime(endTime);

        key = DataSourceKeyUtil.convert("HDQ");
        if (!"".equals(target[0])) {
            TargetType targetType = targetTypeManager.getTargetById(key, new Long(target[0]));
            if (targetType != null)
                entrance.setTargetType(targetType);
        }
        SubType subtype = null;
        if (!"".equals(subType[0]))
            subtype = subTypeManager.getSubTypeById(key, new Long(subType[0]));
        if (subtype != null) {
            entrance.setSubType(subtype);
            if (subtype.getParent() != null)
                entrance.setType(subtype.getParent());
        } else {
            Type t = null;
            t = typeManager.getTypeByName(key, "商品");
            if (t != null)
                entrance.setType(t);
        }
        Date now = new Date();
        entrance.setUpdateTime(now);
        if ("".equals(id[0]))
            entrance.setId(0L);
        // if startTime > now,that means startTime is after now
        if (startTime.compareTo(now) > 0)
            entrance.setStatus(0);
        else
            entrance.setStatus(1);
        if ("HDQ".equals(user.getSite().getCode())) {
            List<Site> siteList = new ArrayList<Site>();
            for (int i = 0; i < siteCodes.length; ++i) {
                key = DataSourceKeyUtil.convert(siteCodes[i]);
                Site s = siteManager.getSiteByCode(key, siteCodes[i]);
                siteList.add(s);
                entrance.getSites().clear();
                entrance.getSites().add(s);
                entranceManager.saveEntrance(key, entrance);
            }
            entrance.getSites().clear();
            for (Site site : siteList)
                entrance.getSites().add(site);
            key = DataSourceKeyUtil.convert("HDQ");
            entranceManager.saveEntrance(key, entrance);
            result = "{'result':'success','message':''}";
        } else {
            entrance.getSites().clear();
            entrance.getSites().add(user.getSite());
            key = DataSourceKeyUtil.convert(user.getSite().getCode());
            entranceManager.saveEntrance(key, entrance);
            result = "{'result':'success','message':''}";
        }

        return result;
    }

    private JSONObject entranceToJson(Entrance entrance) throws JSONException {
        String sites = "";
        Set<Site> siteSet = entrance.getSites();
        for (Site s : siteSet) {
            if (!"HDQ".equals(s.getCode()))
                sites += s.getName() + "  ";
        }
        JSONObject jo = new JSONObject();
        jo.put("id", String.valueOf(entrance.getId()));
        jo.put("code", entrance.getCode());
        jo.put("createTime", DateUtil.convertDateToString("yyyy-MM-dd", entrance.getCreateTime()));
        jo.put("creator", entrance.getCreator().getUsername() + " : " + entrance.getCreator().getSite().getName());
        jo.put("name", entrance.getName());

        if (entrance.getSubType() != null)
            jo.put("subType", entrance.getSubType().getName());
        jo.put("tags", entrance.getTags());
        if (entrance.getTargetType() != null)
            jo.put("targetType", entrance.getTargetType().getName());
        jo.put("url", entrance.getUrl());
        jo.put("status", entrance.getStatus());
        jo.put("sites", sites);
        return jo;
    }

    public SiteManager getSiteManager() {
        return siteManager;
    }

    public void setSiteManager(SiteManager siteManager) {
        this.siteManager = siteManager;
    }

    public TypeManager getTypeManager() {
        return typeManager;
    }

    public void setTypeManager(TypeManager typeManager) {
        this.typeManager = typeManager;
    }
}
